home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
comp0_89.lha
/
Feel
/
Boot
/
Compiler
/
syntx-utl.em
< prev
next >
Wrap
Lisp/Scheme
|
1993-07-12
|
11KB
|
377 lines
;; Eulisp Module
;; Author: pete broadbery
;; File: syntax-utils.em
;; Date: 15/sep/1991
;;
;; Project: Compiler
;; Description:
;; General utils related to ast's
;; Guesses type of fn. calls.
(defmodule syntx-utl
((except (fold) standard)
list-fns
syntx-env
pass
props
stop
)
()
(expose syntx-env)
(defun find-decls (defn)
(cond ((module-definition-p defn)
nil)
((definition-p defn)
(list defn))
((and-decl-p defn)
(fold append
(mapcar find-decls
(and-decl-decls defn))
nil))
((rec-decl-p defn)
(find-decls (rec-decl-decl defn)))))
(export find-decls)
(defgeneric get-internal-closed-bindings (obj))
(defmethod get-internal-closed-bindings ((x syntax-obj))
(fold append
(mapcar get-internal-closed-bindings (subcomponents x))
nil))
(defmethod get-internal-closed-bindings ((x definition))
(if (binding-closed x)
(cons x (call-next-method))
(call-next-method)))
(defmethod get-internal-closed-bindings ((x lambda-term))
;; XXX Not if its inline...
nil)
;; finds the innermost non-tail posn lambda
(defun get-enclosing-object (fn start)
(get-enclose-aux fn (enclosing-block start)))
(defun get-enclose-aux (fn obj)
(if (fn obj)
obj
(get-enclose-aux fn (enclosing-block obj))))
(defun enclosing-lambda (obj)
(get-enclosing-object is-real-lambda obj))
(defgeneric is-real-lambda (obj)
methods ((((x lambda-term))
t)
(((x module-block))
t)
(((x <object>))
nil)))
(defun enclosing-module (x)
(get-enclosing-object module-p x))
(export get-internal-closed-bindings enclosing-lambda)
(defun function-fn (lst)
(cdr (assq 'object lst)))
(defun function-type (lst)
(cdr (assq 'class lst)))
(defun function-prop (lst x)
(cdr (assq x lst)))
;; if we dont know, pretend we do+that it will be sorted out later.
(defun function-nargs (lst)
(let ((type (assq 'argtype lst)))
(if (null type) (cons () 9999)
(cond ((consp (cdr type))
(car (cdr type)))
(t (cons (< (cdr type) 0)
(if (< (cdr type) 0) (- (cdr type)) (cdr type))))))))
(defun function-nary-p (obj)
nil)
;; If at all possible, find the function object referenced by obj.
;; Guessing what a function is.
(defgeneric find-fn (x)
methods ((((x syntax-obj))
(cons (cons 'object x) (unknown-object-properties)))
(((x ident-term))
(let ((props
(cons (cons 'object (ident-decl x)) (read-defn-properties (ident-decl x)))))
(if (eq (function-type props) 'bytefunction)
(cond ((module-definition-p (ident-decl x))
(cons (cons 'class 'local) props))
((definition-p (ident-decl x))
(cons (cons 'class 'lexical) props))
(t props))
props)))
(((x lambda-id))
(cons (cons 'object x) (unknown-object-properties)))
(((x special-term))
(compute-special-proplist x))
(((x abs-definition))
(read-defn-properties x))
(((x applic-term))
(let ((xx (compute-compile-time-proplist x)))
(if (null xx)
(cons (cons 'object x) (unknown-object-properties))
(progn (format t "Inlining ~a~%" (cdar xx))
xx))))
(((x <object>))
(format t "Unknown object: ~a~%" x)
(error "dunno" <clock-tick>))
))
(export function-fn function-type function-nargs function-nary-p find-fn function-prop)
;; accessing an objects property list...
(defun unknown-object-properties ()
'((class . unknown) (mutable nil)))
(defgeneric read-defn-properties (defn)
methods ((((defn imported-definition))
(defn-properties defn))
(((defn local-definition))
(if (decl-done-properties defn)
(defn-properties defn)
(let ((props (compute-properties defn)))
((setter decl-done-properties) defn t)
((setter defn-properties) defn
(append props (defn-properties defn)))
props)))
(((defn lambda-id))
(unknown-object-properties))
(((defn <object>))
(error "no way" <clock-tick>))))
;; Calculate the property list for a binding
(defgeneric compute-properties (defn))
(defmethod compute-properties ((defn local-definition))
(if (binding-mutable defn)
(list (list 'mutable t)
(list 'class 'unknown))
(cons (list 'mutable nil)
(classify (defn-body defn)))))
(defmethod compute-properties ((defn module-definition))
(let ((lst (call-next-method)))
(append (list (list 'address (module-name (enclosing-module defn)) (defn-ide defn)))
(append (list (cons 'name (defn-ide defn)))
lst))))
(defun compute-special-proplist (special)
(generic-classify special))
;; Real analysis: Find the type of a declaration.
;; Returns a-list --- keys: mutable, class (bytefunction, bytemacro, internal,
;; function --- 'C', object), argtype,
(defun classify (obj)
(generic-classify obj))
(defgeneric generic-classify (body))
(defmethod generic-classify ((lam lambda-term))
(list (cons 'class 'bytefunction)
(list 'argtype (lambda-nargs lam))))
(defmethod generic-classify ((mlam macro-lambda-term))
(list (cons 'class 'macro)
(list 'argtype (lambda-nargs mlam))))
(defmethod generic-classify ((x term))
(list (cons 'class 'unknown)))
(defmethod generic-classify ((x special-term))
(cond ((eq (special-term-name x) 'inline-fn)
(list (cons 'class 'inline)
(cons 'argtype (car (special-term-data x)))
(cons 'code (cdr (special-term-data x)))))
((eq (special-term-name x) 'call-next-method-internal)
(list (cons 'object x) (cons 'class 'special)))
(t (cons 'class 'unknown))))
(defun decl-class (x)
(let ((props (read-defn-properties x))
(setter (decl-setter x)))
(if (null setter)
props
(append props
(list (cons 'setter (read-defn-properties setter)))))))
;; (let ((xx (decl-class-uncached x)))
;; (if (null xx)
;; (let ((aa (classify-decl x)))
;; ((setter decl-class-uncached) x aa)
;; aa)
;; xx))
(defun std-class-list (x)
;; just the address at the moment...
(cons (cons 'name (defn-ide x))
(cons (list 'address (module-name (enclosing-module x)) (defn-ide x))
(let ((xx nil)) ;;; (obj-setter x)
(if (null xx)
nil
(list (cons 'setter (decl-class xx))))))))
(export decl-class)
;; dependencies...
(defun add-dependency (mod defn)
(if (memq (import-home defn) (module-dependencies mod))
nil
((setter module-dependencies) mod
(cons (import-home defn) (module-dependencies mod)))))
(export add-dependency)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun compute-compile-time-proplist (x)
(let ((val (compute-compile-time-value x)))
(if (abs-definition-p val)
(cons (cons 'object val) (read-defn-properties val))
nil)))
(defgeneric compute-compile-time-value (x))
(defmethod compute-compile-time-value ((app applic-term))
(let ((fn (compile-time-value (applic-fun app)))
(args (applic-args app)))
(cond ((null fn) nil)
((setter-function-p fn)
(find-setter (compile-time-value (car args))))
(t nil))))
(defmethod compute-compile-time-value ((x ident-term))
(compute-compile-time-value (car (ident-defblock x))))
(defmethod compute-compile-time-value ((x module-definition))
(if (binding-mutable x) nil x))
(defmethod compute-compile-time-value ((x imported-definition))
x)
(defmethod compute-compile-time-value ((x syntax-obj))
nil)
;; Generic --- could look at the property thang...
;;
;; nasty local-defn case cos of
;; (let ((x (if foo a b)))
;; ((setter x) y))
(defgeneric find-setter (value)
methods ((((defn imported-definition))
(import-defn-setter defn))
(((defn local-definition))
(decl-setter defn))
(((o <object>))
nil)))
(defun compile-time-value (x)
(let ((xx (cached-compile-time-value x)))
(cond ((null xx)
(let ((val (compute-compile-time-value x)))
((setter cached-compile-time-value) x
(if (null val) 'no-way val))
val))
((eq xx 'no-way) nil)
(t xx))))
;; setting setter functions
(defgeneric set-setter-function (fn new-setter)
methods ((((ident ident-term) new-setter)
(set-setter-function (ident-decl ident) new-setter))
((thing (ide ident-term))
(set-setter-function thing (ident-decl ide)))
(((decl local-definition) (setter-decl module-definition))
(if (or (binding-mutable decl)
(binding-mutable setter-decl))
nil
((setter decl-setter) decl setter-decl)))
(((decl imported-definition) (setter-decl module-definition))
(if (or (binding-mutable decl)
(binding-mutable setter-decl))
nil
(add-defn-prop decl 'setter (read-defn-properties setter-decl))))
(((o1 <object>) (o2 <object>))
nil)))
(defun setter-function-p (x)
(let ((aa (defn-prop-ref x 'setter-function)))
aa))
;; end module
)
(defgeneric find-fn (obj)
methods ((((x syntax-obj))
(list x 'unknown 0))
(((x applic-term))
(let ((xx (compile-time-value x)))
(if (null xx)
(list x 'unknown 0)
(find-fn xx))))
(((x lambda-term))
;;(format t "Lambda: nargs: ~a~%" (lambda-nargs x))
(list x 'bytefunction (lambda-nargs x)))
(((x ident-term))
(let ((props (read-defn-properties (ident-decl x))))
(list (ident-decl x) 'unknown 0)))
;;(let ((xx (find-fn (car (ident-defblock x)))))
;;(if (and (eq (function-type xx) 'local-defun)
;;(eq (car xx) (enclosing-lambda x)))
;;(cons (car xx)
;;(cons 'lexical
;;(cddr xx)))
;;xx))
(((x definition))
(if (defn-mutable-p x)
(list x 'unknown 0)
(let ((actual (find-fn (defn-body x))))
;; try to env+call via a jump
(cond ((eq (function-type actual) 'bytefunction)
(cons (car actual)
(cons 'lexical ;; was local-defun
(cddr actual))))
((eq (function-type actual) 'special)
actual)
(t (list x 'unknown 0))))))
(((x module-definition))
(if (defn-mutable-p x)
(list x 'unknown 0)
(let ((actual (find-fn (defn-body x))))
(cond ((eq (function-type actual) 'bytefunction)
(cons (car actual)
(cons 'local
(cddr actual))))
((eq (function-type actual) 'special)
actual)
(t (list x 'unknown 0))))))
(((x imported-definition))
;; defined in syntax-utils
(list x (import-object-type x)
(import-function-nargs x)))
(((x special-term))
(list x 'special 0))
(((x object))
;;(format t "Find Fn Got Strange: ~a~%" x)
(stop x))))